#include <stdio.h>	
#include <string.h>
#include <evalsoc.h>

#include "test_spi.h"
#include "echeck.h"
#include "test_dma.h"
#include "evalsoc_spi.h"




int spi_case2(uint32_t base_address){
    dw_spi_regs_t * pspi = (dw_spi_regs_t *)base_address;
    uint8_t tx_data[] = {0xAA, 0xBB, 0xCC, 0xDD};
    uint8_t rx_data[4] = {0};

    // Disable SPI before configuration
    pspi->SSIENR = 0x0;

    // Configure SPI master mode - ensure CPOL=0, CPHA=0 matches slave
    pspi->CTRLR0 = 0x10000C7; // Transmit and Receive mode, CPOL=1, CPHA=1
    pspi->BAUDR = 0x06;    // Set baud rate ---least 0x6(Target TMOD=receive only--8.33MHz)
    pspi->IMR = 0x0;      // disable all interrupts
    pspi->SER = 0x1;      // Enable slave select 0

    // Enable SPI
    pspi->SSIENR = 0x1;

    printf("SPI Master initialized. Starting transmission...\n");
	
    // Send data
    printf("Sending data...\n");
    for(int i = 0; i < 4; i++) {
        pspi->DR[0] = tx_data[i];
    }

    // Wait for transmission to complete
    while((pspi->SR & 0x4) == 0) {		
        __NOP();
    }
    // Receive data
    printf("Receiving data...\n");
    for(int i = 0; i < sizeof(rx_data); i++) {
        while((pspi->SR & 0x8) == 0 ) {
            __NOP();
        }
        rx_data[i] = pspi->DR[0];
    }

    // Print received data
    printf("Received data: ");
    for(int i = 0; i < sizeof(rx_data); i++) {
        printf("%02X ", rx_data[i]);
    }
    printf("\n");

    // Disable SPI
    pspi->SSIENR = 0x0;
    printf("SPI communication completed\n");

    return 0;
}

/**
 * @brief  dma到spi的测试函数 tx模式
 * @param  channer: dma通道号
 * @param  dma_tx_req: dma请求号
 * @param  Memory_addr: 内存地址
 * @param  width: 宽度
 * @param  msize: 块大小
 * @param  len: 长度
 * @return 0
 */
int spi_dma_spi_tx(uint32_t spi_base,uint32_t channer,uint32_t dma_tx_req,uint32_t Memory_addr,uint32_t len){
	dw_spi_regs_t * pspi = (dw_spi_regs_t *)spi_base;

	memset((void *)Memory_addr,0xAA,len);

	dma_init_M2P(channer,dma_tx_req,Memory_addr,(uint32_t)(spi_base+0x60),0,0,len);

	while( (pspi->SR & 0x10) == 0 ) {
		__NOP();
	}

	for( int i=0;i<len;i++){
		while ((pspi->SR & 0x4) ==0); // 	
		uint16_t received_data = pspi->DR[0];
		if(received_data!= 0xAA){
			return -1;
		}
	}
	printf("spi dma tx test success\n");
	pspi->SSIENR = 0x0; // disable spi
	return 0;
}
/**
 * @brief  spi到dma的测试函数 rx模式
 * @param  spi_base: spi的基地址
 * @param  channer: dma通道号
 * @param  dma_rx_req: dma请求号
 * @param  Memory_addr: 内存地址
 * @param  len: 长度
 * @return 0
 */
int spi_dma_spi_rx(uint32_t spi_base,uint32_t channer,uint32_t dma_rx_req,uint32_t Memory_addr,uint32_t len){

	struct dw_dma_regs *dma_regs = (struct dw_dma_regs *)0x00100000;
	dw_spi_regs_t * pspi = (dw_spi_regs_t *)spi_base;

	dma_init_P2M(channer,dma_rx_req,(uint32_t)(spi_base+0x60),Memory_addr,0,0,len);
	

	for(int i=0;i<len*2;i++){
		pspi->DR[0] = 0xAA;
	}

	// 等待接收完成
	while ( (pspi->SR & 0x4) == 0 )  {	
		__NOP();
	}



	while (dma_regs->CH_EN & (0x1<<channer)); // 等待DMA传输完成

	for(int i=0;i<len;i++){
		if((read_reg(Memory_addr++)&0xFF)!= 0xaa){
			printf("received data = %x\r\n",read_reg(Memory_addr));
			printf("error\r\n");
			return -1;
		}
	}
	printf("spi dma rx test success\n");
	pspi->SSIENR = 0x0; // disable spi
	return 0;	
}


void dma_spi_case_tx(void){
	spi_init(SPI0_BASE,Loopback_TESTING_MODE);
	spi_dma_spi_tx(SPI0_BASE,2,0x6,0x00090A00,501);

	return;
}
void dma_spi_case_rx(void){
	spi_init(SPI0_BASE,Loopback_TESTING_MODE);
	spi_dma_spi_rx(SPI0_BASE,3,0x7,0x00090C00,201);
	return;
}

// spi
int dbg_test_spi( void * parg, int argc, const char * argv[] )
{
	spi_case2(SPI0_BASE);//spi master tx

	return 0;

}

// spi slave
int dbg_test_spi_slave( void * parg, int argc, const char * argv[] )
{
	spi_slave_init(SPI1_BASE,Loopback_NORMAL_MODE);//spi slave rx

	return 0;

}